#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
交易管理器
负责订单的下达、跟踪和管理
"""

import asyncio
from typing import Dict, Any, Optional, List
from datetime import datetime
from enum import Enum

from config.config_manager import get_config
from utils.logger import get_logger, trade_log
from utils.exceptions import TradingError, OrderError, OrderTimeoutError
from core.api_manager import get_api_manager
from core.base_classes import BaseOrderManager


class OrderStatus(Enum):
    """订单状态"""
    PENDING = "PENDING"       # 待提交
    ALIVE = "ALIVE"          # 已提交未成交
    FINISHED = "FINISHED"    # 已完成
    CANCELLED = "CANCELLED"  # 已撤销
    REJECTED = "REJECTED"    # 已拒绝


class Order:
    """订单对象"""

    def __init__(self, order_id: str, symbol: str, direction: str,
                 offset: str, volume: int, price: Optional[float] = None):
        self.order_id = order_id
        self.symbol = symbol
        self.direction = direction
        self.offset = offset
        self.volume = volume
        self.price = price

        # 订单状态
        self.status = OrderStatus.PENDING
        self.volume_traded = 0
        self.volume_left = volume

        # 时间戳
        self.create_time = datetime.now()
        self.update_time = datetime.now()

        # 交易结果
        self.trade_price = None
        self.commission = 0.0

    def update_status(self, status: OrderStatus, volume_traded: int = None,
                     trade_price: float = None):
        """更新订单状态"""
        self.status = status
        self.update_time = datetime.now()

        if volume_traded is not None:
            self.volume_traded = volume_traded
            self.volume_left = self.volume - volume_traded

        if trade_price is not None:
            self.trade_price = trade_price

    def is_completed(self) -> bool:
        """检查订单是否完成"""
        return self.status in [OrderStatus.FINISHED, OrderStatus.CANCELLED, OrderStatus.REJECTED]

    def is_active(self) -> bool:
        """检查订单是否活跃"""
        return self.status == OrderStatus.ALIVE

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            'order_id': self.order_id,
            'symbol': self.symbol,
            'direction': self.direction,
            'offset': self.offset,
            'volume': self.volume,
            'price': self.price,
            'status': self.status.value,
            'volume_traded': self.volume_traded,
            'volume_left': self.volume_left,
            'trade_price': self.trade_price,
            'create_time': self.create_time.isoformat(),
            'update_time': self.update_time.isoformat()
        }


class TradingManager(BaseOrderManager):
    """交易管理器"""

    def __init__(self):
        super().__init__(None)  # API客户端稍后设置
        self.config = get_config()

        # 订单存储
        self.orders = {}  # order_id -> Order
        self.pending_orders = []  # 待处理的订单

        # 统计信息
        self.total_orders = 0
        self.successful_orders = 0
        self.failed_orders = 0

        self.logger.info("交易管理器初始化完成")

    async def initialize(self, api_manager):
        """初始化交易管理器"""
        self.api_client = api_manager
        self.logger.info("交易管理器初始化API客户端成功")

    async def place_order(self, symbol: str, direction: str, offset: str,
                         volume: int, price: Optional[float] = None,
                         order_type: str = "LIMIT") -> str:
        """下单"""
        try:
            self.logger.info(f"准备下单: {symbol} {direction} {offset} {volume}手 @ {price}")

            # 生成订单ID
            order_id = f"order_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"

            # 创建订单对象
            order = Order(order_id, symbol, direction, offset, volume, price)
            self.orders[order_id] = order
            self.pending_orders.append(order)

            # 实际下单
            actual_order_id = await self.api_client.insert_order(
                symbol, direction, offset, volume, price
            )

            # 更新订单ID（如果API返回了实际订单ID）
            if actual_order_id != order_id:
                order.order_id = actual_order_id
                self.orders[actual_order_id] = order
                del self.orders[order_id]
                order_id = actual_order_id

            # 更新订单状态
            order.update_status(OrderStatus.ALIVE)

            self.total_orders += 1
            trade_log(symbol, f"{direction}_{offset}", volume, price, order_id)

            self.logger.info(f"订单已提交: {order_id}")
            return order_id

        except Exception as e:
            self.failed_orders += 1
            self.logger.error(f"下单失败: {e}")
            raise TradingError(f"下单失败: {e}")

    async def cancel_order(self, order_id: str) -> bool:
        """撤单"""
        try:
            if order_id not in self.orders:
                self.logger.warning(f"订单不存在: {order_id}")
                return False

            order = self.orders[order_id]

            if not order.is_active():
                self.logger.warning(f"订单不可撤销: {order_id} 状态={order.status.value}")
                return False

            # 执行撤单
            success = await self.api_client.cancel_order(order_id)

            if success:
                order.update_status(OrderStatus.CANCELLED)
                self.logger.info(f"撤单成功: {order_id}")
                return True
            else:
                self.logger.error(f"撤单失败: {order_id}")
                return False

        except Exception as e:
            self.logger.error(f"撤单异常: {e}")
            return False

    async def get_order_status(self, order_id: str) -> Dict[str, Any]:
        """获取订单状态"""
        try:
            if order_id not in self.orders:
                return {'error': 'Order not found'}

            order = self.orders[order_id]

            # 从API获取最新状态（如果需要）
            # 这里可以添加从API同步最新状态的逻辑

            return order.to_dict()

        except Exception as e:
            self.logger.error(f"获取订单状态失败: {e}")
            return {'error': str(e)}

    async def get_active_orders(self, symbol: Optional[str] = None) -> List[Dict[str, Any]]:
        """获取活跃订单"""
        try:
            active_orders = []

            for order in self.orders.values():
                if order.is_active():
                    if symbol is None or order.symbol == symbol:
                        active_orders.append(order.to_dict())

            return active_orders

        except Exception as e:
            self.logger.error(f"获取活跃订单失败: {e}")
            return []

    async def cancel_all_orders(self, symbol: Optional[str] = None) -> int:
        """撤销所有订单"""
        try:
            cancelled_count = 0

            for order_id, order in list(self.orders.items()):
                if order.is_active():
                    if symbol is None or order.symbol == symbol:
                        success = await self.cancel_order(order_id)
                        if success:
                            cancelled_count += 1

            self.logger.info(f"批量撤单完成: {cancelled_count} 个订单")
            return cancelled_count

        except Exception as e:
            self.logger.error(f"批量撤单失败: {e}")
            return 0

    async def update_orders_status(self):
        """更新所有订单状态"""
        try:
            # 获取API中的订单信息
            api_orders = await self.api_client.get_order()

            if not api_orders:
                return

            # 更新本地订单状态
            for order_id, order_info in api_orders.items():
                if order_id in self.orders:
                    local_order = self.orders[order_id]

                    # 更新成交数量
                    volume_traded = order_info.get('volume_traded', 0)
                    trade_price = order_info.get('trade_price')

                    # 更新状态
                    if order_info.get('status') == 'FINISHED':
                        local_order.update_status(OrderStatus.FINISHED, volume_traded, trade_price)
                        self.successful_orders += 1
                    elif order_info.get('status') == 'CANCELLED':
                        local_order.update_status(OrderStatus.CANCELLED, volume_traded, trade_price)
                    elif order_info.get('status') == 'REJECTED':
                        local_order.update_status(OrderStatus.REJECTED, volume_traded, trade_price)
                        self.failed_orders += 1

        except Exception as e:
            self.logger.error(f"更新订单状态失败: {e}")

    async def cleanup_completed_orders(self):
        """清理已完成的订单"""
        try:
            completed_ids = []

            for order_id, order in list(self.orders.items()):
                if order.is_completed():
                    # 保留最近的订单记录，清理太旧的
                    if (datetime.now() - order.create_time).days > 7:
                        completed_ids.append(order_id)

            for order_id in completed_ids:
                del self.orders[order_id]

            if completed_ids:
                self.logger.info(f"清理完成订单: {len(completed_ids)} 个")

        except Exception as e:
            self.logger.error(f"清理订单失败: {e}")

    async def get_trading_summary(self) -> Dict[str, Any]:
        """获取交易摘要"""
        try:
            active_orders = await self.get_active_orders()
            completed_orders = [order for order in self.orders.values() if order.is_completed()]

            return {
                'total_orders': self.total_orders,
                'active_orders': len(active_orders),
                'completed_orders': len(completed_orders),
                'successful_orders': self.successful_orders,
                'failed_orders': self.failed_orders,
                'success_rate': (self.successful_orders / self.total_orders) if self.total_orders > 0 else 0,
                'active_orders_detail': active_orders
            }

        except Exception as e:
            self.logger.error(f"获取交易摘要失败: {e}")
            return {'error': str(e)}

    async def place_market_order(self, symbol: str, direction: str, offset: str, volume: int) -> str:
        """市价单"""
        return await self.place_order(symbol, direction, offset, volume, None, "MARKET")

    async def place_limit_order(self, symbol: str, direction: str, offset: str,
                               volume: int, price: float) -> str:
        """限价单"""
        return await self.place_order(symbol, direction, offset, volume, price, "LIMIT")

    async def place_stop_order(self, symbol: str, direction: str, offset: str,
                              volume: int, stop_price: float) -> str:
        """止损单"""
        # 这里可以实现止损单逻辑
        return await self.place_order(symbol, direction, offset, volume, stop_price, "STOP")

    async def get_position_info(self, symbol: str) -> Dict[str, Any]:
        """获取持仓信息"""
        try:
            position = await self.api_client.get_position(symbol)

            if not position:
                return {
                    'symbol': symbol,
                    'pos_long': 0,
                    'pos_short': 0,
                    'float_profit': 0.0
                }

            return {
                'symbol': symbol,
                'pos_long': position.get('pos_long', 0),
                'pos_short': position.get('pos_short', 0),
                'float_profit': position.get('float_profit_long', 0) + position.get('float_profit_short', 0)
            }

        except Exception as e:
            self.logger.error(f"获取持仓信息失败: {e}")
            return {'error': str(e)}

    async def close_position(self, symbol: str) -> bool:
        """平仓"""
        try:
            position_info = await self.get_position_info(symbol)

            if position_info.get('pos_long', 0) > 0:
                # 平多仓
                await self.place_market_order(symbol, "SELL", "CLOSE",
                                            position_info['pos_long'])
                self.logger.info(f"平多仓: {symbol} {position_info['pos_long']}手")

            if position_info.get('pos_short', 0) > 0:
                # 平空仓
                await self.place_market_order(symbol, "BUY", "CLOSE",
                                            position_info['pos_short'])
                self.logger.info(f"平空仓: {symbol} {position_info['pos_short']}手")

            return True

        except Exception as e:
            self.logger.error(f"平仓失败: {e}")
            return False


# 全局交易管理器实例
_trading_manager = None

def get_trading_manager() -> TradingManager:
    """获取全局交易管理器实例"""
    global _trading_manager
    if _trading_manager is None:
        _trading_manager = TradingManager()
    return _trading_manager

async def init_trading_manager(api_manager) -> TradingManager:
    """初始化交易管理器"""
    global _trading_manager
    _trading_manager = TradingManager()
    await _trading_manager.initialize(api_manager)
    return _trading_manager
